package com.yvtian.admin.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.mysql.cj.util.StringUtils;
import com.yvtian.admin.dao.SysRoleDao;
import com.yvtian.admin.dto.ReqRole;
import com.yvtian.admin.pojo.SysRole;
import com.yvtian.admin.pojo.SysUser;
import com.yvtian.admin.service.SysRoleService;
import com.yvtian.admin.vo.RoleVO;
import com.yvtian.admin.vo.UserInfoResponse;
import com.yvtian.admin.vo.UserVO;
import com.yvtian.exception.RecordException;
import com.yvtian.utils.DateUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

@Service
@Transactional
public class SysRoleServiceImpl extends ServiceImpl<SysRoleDao, SysRole> implements SysRoleService {

    @Autowired
    private SysRoleDao roleDao;

    @Override
    public SysRole findRoleByRoleId(Integer roleId) {
        return roleDao.selectById(roleId);
    }

    @Override
    public void addRole(ReqRole reqRole) {
        QueryWrapper<SysRole> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("name", reqRole.getName());
        Integer integer = roleDao.selectCount(queryWrapper);
        if (integer > 0) {
            throw new RecordException("角色已存在");
        }
        SysRole sysRole = new SysRole();
        BeanUtils.copyProperties(reqRole, sysRole);
        Date date = new Date();
        sysRole.setCreateTime(date);
        sysRole.setUpdateTime(date);
        sysRole.setIsDelete("0");
        roleDao.insert(sysRole);
        SysRole sysRole1 = roleDao.selectOne(queryWrapper);
        Integer roleId = sysRole1.getId();
        if (reqRole.getPermissions().size() != 0) {
            roleDao.addPermissionForRole(roleId, reqRole.getPermissions());
        }
    }

    @Override
    public void delRole(ArrayList<Integer> roleIds) {
        List<SysRole> roles = findList(roleIds);
        if (roles.size() == 0) {
            throw new RecordException("未找到记录");
        }
        roleDao.deleteBatchIds(roleIds);
        roleDao.deleteByRolePers(roleIds);
        roleDao.deleteByUserRole(roleIds);
    }

    @Override
    public void updateRole(Integer roleId, ArrayList<Integer> menuIds, Map<String, Object> columnData) {
        UpdateWrapper<SysRole> wrapper = new UpdateWrapper<>();
        for (String key : columnData.keySet()) {
            wrapper.set(key, columnData.get(key));
        }
        wrapper.eq("id", roleId);
        wrapper.set("update_time", new Date());
        roleDao.update(null, wrapper);
        //删除该角色所有的菜单权限
        roleDao.deleteByRoleMenu(roleId);
        //赋予该角色菜单权限
        if (null == menuIds || menuIds.size() == 0) {
            return;
        }
        roleDao.addMenuForRole(roleId, menuIds);
    }

    @Override
    public IPage<SysRole> findByPage(Page<SysRole> page, RoleVO roleVO) {

        LambdaQueryWrapper<SysRole> sysRoleLambdaQueryWrapper = new LambdaQueryWrapper<>();
        sysRoleLambdaQueryWrapper.eq(SysRole::getIsDelete, 0);
        if (roleVO.getId() != null) {
            sysRoleLambdaQueryWrapper.eq(SysRole::getId, roleVO.getId());
        }
        if (!StringUtils.isNullOrEmpty(roleVO.getCode())) {
            sysRoleLambdaQueryWrapper.eq(SysRole::getCode, roleVO.getCode());
        }
        if (!StringUtils.isNullOrEmpty(roleVO.getDes())) {
            sysRoleLambdaQueryWrapper.like(SysRole::getDes, roleVO.getDes());
        }
        if (!StringUtils.isNullOrEmpty(roleVO.getName())) {
            sysRoleLambdaQueryWrapper.like(SysRole::getName, roleVO.getName());
        }
        if (ObjectUtils.isNotNull(roleVO.getIsDisable())) {
            sysRoleLambdaQueryWrapper.eq(SysRole::getIsDisable, roleVO.getIsDisable());
        }
        return this.page(page, sysRoleLambdaQueryWrapper);
    }

    @Override
    public void changeDisable(String disable, Integer roleId) {
        UpdateWrapper<SysRole> updateWrapper = new UpdateWrapper<>();
        updateWrapper.eq("id", roleId);
        updateWrapper.set("is_disable", disable);
        roleDao.update(null, updateWrapper);
    }

    @Override
    public List<RoleVO> findBatchByRoleIds(ArrayList<Integer> roleIds) {
        List<RoleVO> roleVOS = new ArrayList<>();
        List<SysRole> SysRoles = roleDao.selectBatchIds(roleIds);
        for (SysRole SysRole : SysRoles) {
            RoleVO roleVO = new RoleVO();
            BeanUtils.copyProperties(SysRole, roleVO);
            roleVOS.add(roleVO);
        }
        return roleVOS;
    }

    @Override
    public void updateRoleToUser(ArrayList<Integer> roleIds, String userId) {
        roleDao.delAllRoleToUser(userId);
        roleDao.addRolesToUser(roleIds, userId);
    }

    @Override
    public UserVO findUserByRole(Integer roleId, Integer currentPage, Integer pageSize, String nickname, String mobile) {
        int userCount = roleDao.findUserCountByRoleId(roleId, nickname, mobile);
        UserVO userVO = new UserVO();
        ArrayList<UserInfoResponse> users = new ArrayList<>();
        if (userCount == 0) {
            userVO.setUserInfo(users);
            userVO.setSize(pageSize);
            return userVO;
        }
        int flag = currentPage == 1 ? 0 : currentPage;
        int offset = flag * pageSize;
        ArrayList<SysUser> sysUsers = roleDao.findUserByRoleId(roleId, offset, pageSize, nickname, mobile);
        for (SysUser SysUser : sysUsers) {
            UserInfoResponse userInfoResponse = new UserInfoResponse();
            BeanUtils.copyProperties(SysUser, userInfoResponse);
            users.add(userInfoResponse);
        }
        userVO.setSize(users.size());
        currentPage = currentPage == 0 ? 1 : currentPage;
        userVO.setCurrent(currentPage);
        userVO.setTotal(userCount);
        userVO.setUserInfo(users);
        return userVO;
    }

    @Override
    public void delUserRoleByUserIds(Integer roleId, ArrayList<String> userIds) {
        roleDao.delUserRoleByUserIds(roleId, userIds);
    }

    @Override
    public UserVO findUserNotInRole(Integer roleId, Integer pageNum, Integer pageSize, String nickName, String mobile) {
        int userCount = roleDao.findUserCountNotInRole(roleId, nickName, mobile);
        UserVO userVO = new UserVO();
        ArrayList<UserInfoResponse> users = new ArrayList<>();
        if (userCount == 0) {
            userVO.setTotal(0);
            userVO.setUserInfo(users);
            return userVO;
        }
        int pageFlag = pageNum == 1 ? 0 : pageNum;
        ArrayList<SysUser> sysUsers = roleDao.findUserNotInRole(roleId, pageFlag, pageSize, nickName, mobile);
        for (SysUser SysUser : sysUsers) {
            UserInfoResponse user = new UserInfoResponse();
            BeanUtils.copyProperties(SysUser, user);
            users.add(user);
        }
        userVO.setTotal(userCount);
        userVO.setUserInfo(users);
        userVO.setCurrent(pageNum == 0 ? 1 : pageNum);
        userVO.setSize(users.size());
        return userVO;
    }

    @Override
    public void addRoleToUser(Integer roleId, ArrayList<String> userIds) {
        roleDao.addRoleToUsers(roleId, userIds);
    }

    @Override
    public List<List<String>> export() {
        List<SysRole> SysRoles = roleDao.selectList(null);
        //List<String> roleColumnName = roleService.findColumnName();
        return getRoleList(SysRoles);
    }

    public List<SysRole> findList(ArrayList<Integer> ids) {
        return roleDao.selectBatchIds(ids);
    }

    private List<List<String>> getRoleList(List<SysRole> SysRoles) {
        List<List<String>> lists = new ArrayList<>();
        for (SysRole role : SysRoles) {
            List<String> list = new ArrayList<>();
            list.add(String.valueOf(role.getId()));
            list.add(role.getName());
            list.add(role.getDes());
            list.add(DateUtils.format(DateUtils.FormatType.type2, role.getCreateTime()));
            list.add(DateUtils.format(DateUtils.FormatType.type2, role.getUpdateTime()));
            if (String.valueOf(role.getIsDisable()).equals("0")) {
                list.add("启用");
            } else {
                list.add("停用");
            }
            lists.add(list);
        }
        return lists;
    }

}
